package main

import (
	"fmt"
	"time"
)

//1,普通通道
func channel() {

	//创建通道,读写都是阻塞的
	//默认通道无缓冲的,要等对应通道准备好接收，才允许发送
	var channel chan string = make(chan string)

	//携程,发送值到通道
	go func (){
		channel <- "2018"
	}()

	//读取通道值
	val := <- channel

	fmt.Print("从通道读取值为:"+val)
}

//2,通道缓冲
func channel_buffer() {

	// 缓存通道,最多允许缓存3个值
	// 这个通道是有缓冲区的,
	// 即使没有一个对应的并发接收方,
	// 我们仍然可以发送这些值
	var channel chan string = make(chan string, 3)

	channel <- "0"
	channel <- "1"
	channel <- "2"

	fmt.Print(<- channel)
	fmt.Print(<- channel)
	fmt.Print(<- channel)
}

//3,通道同步
func channel_notice() {

	//通道是同步的,在未接到call()通知前
	//程序一直阻塞的
	var call = func (n chan bool) {

		fmt.Print("Work ...\r\n")

		time.Sleep(time.Second)

		fmt.Print("Done ...\r\n")

		n <- true
	}

	var notice chan bool = make(chan bool)

	go call(notice)

	<- notice
}

//通道方向
func channel_direction() {


	var receive func(r chan <- string, msg string) = func(r chan <- string, msg string) {
		r <- msg
	}

	/**
	 * 从r通道接收的数据并发送给通道
	 */
	var send func (r <- chan string, s chan <- string) = func (r <- chan string, s chan <- string) {
		s <- <- r
	}

	R := make(chan string, 1)
	S := make(chan string, 1)

	receive(R, "Hello, World!!")

	send(R, S)

	fmt.Print(<- S)
}

//通道选择器
func channel_select () {

	a := make(chan string)
	b := make(chan string)

	go func (){
		time.Sleep(time.Second)
		a <- "Sleep 1\r\n"
	}()

	go func (){
		time.Sleep(time.Second * 2)
		b <- "Sleep 2\r\n"
	}()

	for i := 0; i < 2; i++ {
		select {
			case msg := <- a:
				fmt.Print(msg)
			case msg2 := <- b:
				fmt.Print(msg2)
		}
	}
}

func main () {

	//channel()

	//channel_buffer()

	//channel_notice()

	//channel_direction()

	channel_select()
}